#include "HashTable.hpp"

namespace Myunordered_map
{
    template <class K, class V, class Hash = HashFunc<K>>
    class unordered_map
    {
        struct MapKeyOfT
        {
            const K &operator()(const std::pair<K, V> &kv)
            {
                return kv.first;
            }
        };

    public:
        typedef typename hash_bucket::HashTable<K, std::pair<const K, V>, MapKeyOfT, Hash>::iterator iterator;
        iterator begin()
        {
            return _ht.begin();
        }

        iterator end()
        {
            return _ht.end();
        }

        V &operator[](const K &key)
        {
            //iterator指向一个pair<K,V>类型
            std::pair<iterator, bool> ret = insert(std::make_pair(key, V()));
            return ret.first->second;
        }

        std::pair<iterator, bool> insert(const std::pair<K, V> &kv)
        {
            return _ht.Insert(kv);
        }

        iterator find(const std::pair<K, V> &kv)
        {
            MapKeyOfT kot;
            return _ht.Find(kot(kv));
        }

        bool erase(const std::pair<K, V> &kv)
        {
            MapKeyOfT kot;
            return _ht.Erase(kot(kv));
        }

    private:
        hash_bucket::HashTable<K, std::pair<const K, V>, MapKeyOfT, Hash> _ht;
    };

    void test_unordered_map()
    {
        std::string arr[] = {"苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
                             "苹果", "香蕉", "苹果", "香蕉", "苹果", "草莓", "苹果", "草莓"};
        unordered_map<std::string, int> countMap;
        for (auto &e : arr)
        {
            countMap[e]++;
        }

        unordered_map<std::string, int>::iterator it = countMap.begin();
        while (it != countMap.end())
        {
            // it->first += 'x'; // key不能修改
            it->second += 1; // value可以修改
            std::cout << it->first << ":" << it->second << std::endl;
            ++it;
        }
        std::cout << std::endl;

        for (auto &kv : countMap)
        {
            std::cout << kv.first << ":" << kv.second << std::endl;
        }
        std::cout << std::endl;
    }
}